Skip to content

Conversation

@VeckoTheGecko
Copy link
Contributor

@VeckoTheGecko VeckoTheGecko commented Oct 31, 2025

(posting now for visibility and to request feedback/pixi debugging help)

Overview

Fixes #10732

This PR migrates the dev workflow and CI for Xarray across to Pixi, providing the following benefits:

  • Composable environments via dependency groups (in pixi called "features")
  • Support for multiple environments
  • Task running
  • lock file support

See the original issue for more info.

Changes so far in this PR:

  • Add pixi badge to readme
  • Migrated most environment files to Pixi config in pixi.toml split apart into features that I thought were sensible . I left out environment-benchmarks.yml, binder/environment as that has interactions with asv, and Binder - this PR is already big enough, and I think those should be explored another time.
    • I made the environments in Pixi have similar names as the original conda environments to ease migration
  • Introduced a cache-pixi-lock.yml workflow (see below section "Considerations")
  • Updated ci.yaml
    • Fixed now! 98% there - for some reason the CI of Pixi is finding which pytest to be .pixi/envs/default/Scripts/pytest while local pixi run -e test-all-deps-py313 which pytest is finding .pixi/envs/test-all-deps-py313/bin/pytest (see test-pixi-dust branch, example action run) . Any ideas why @lucascolley ?
  • Update CI additional
  • Update RTD build
  • Migrate minimal environment to Pixi as well
  • Update contributing guidelines (see "Feedback wanted" section below)
  • Migrate hypothesis tests
  • Migrate nightly dev testing

I've tried to make the commits tidy to help with reviewing commit by commit, which might be easier. I also was quite diligent when migrating from the old env files to make sure versions were the same.

Testing instructions

Resources: Pixi Scipy 2025 talk | Docs: Manifest Reference

  • pixi info -> show info about the pixi environments
  • Build documentation: pixi run doc
  • Run tests: pixi run test then choose the environment you want to run the tests in (or pixi run -e environment_name test)
    • Most often you'll want the test-all-deps-py313 environment (corresponding to the old environment ci/requirements/environment.yml)
  • Run pre-commit: pixi run pre-commit
  • Run mypy typing: pixi run typing

Enter an environment (equivalent to conda activate): pixi shell -e env_name
Exit an environment (equivalent to conda activate): exit or Ctrl+D

See all tasks: pixi run

Considerations

Lock files o' lock files

There was some interesting conversation in #10732 (comment) about lock files. To summarise:

We have two choices to handle the lock files, either (a) generate them in CI, or (b) commit them to the repo and periodically update them.

(a) generating in CI (done in this PR):

  • add pixi.lock to .gitignore
  • have a workflow which generates the lock file. Cache this under a key that is date + hash(pixi.toml)
  • have all workflows restore this pixi.lock file for environment creation

Pros:

  • lock file is only generated once a day and shared across workflows - saving 40s per run
  • close to what was previously done (with daily caches)
  • minimal changes to workflows (only need to add a few lines - cache-pixi-lock.yml is re-usable across different projects).

Cons:

  • Mismatch of devs pixi.lock and what's in CI. Local developers need to periodically delete pixi.lock and regenerate it.
  • Missed benefit of perfectly reproducible dev environments cross developers and with CI

(b) commit the lock files

(I think this is the gist of it)

  • commit the lock file (now local devs and CI can use this lockfile) - around 40k lines
  • add GitHub PR automation to automatically update the lockfile every 3 weeks
  • Most of CI works from committed lockfile, but there can be a job bleeding-edge which runs every few days by taking the current lockfile, running an update, and then running tests. Any failures can be automatically reported in an issue
    • Then, to "resolve" that issue you can add a pin in the pixi.toml manifest and talk with upstream to see whats up

Pros:

  • no need to generate lock files in CI
  • perfectly reproducible dev environments cross developers and CI

Cons:

  • there is a bunch of added complexity/maintainer burden to setting this up (automated workflows etc)

@lucascolley knows the full extent as he's been exploring this setup at Scipy

Conclusion

Approach (a) has minimal setup/maintenance with little downside. I think that it's a good solution for smaller projects in particular (we've adopted it at Parcels - cc @maxrjones might be interesting based on your comment )

Approach (b) is more robust if having the same environment between all devs is highly valued (@shoyer mentioned during a dev meeting that this would be good for xarray), but requires more setup.

I recommend we go for (a) as is done in this PR, and consider (b) separately .

@lucascolley would it be beneficial to do a write-up of all this on prefix.dev sometime to help guide others dealing with this? I'm happy to write or collab on a blog post.

Feedback wanted: To what extent do we promote Conda dev workflows

Yeah - I don't know. In the projects I'm working on I've gone full Pixi, but those are smaller projects.

I've deleted the old environment files to avoid duplication, but can re-add them to the extent which you want to support conda dev workflows.

I've held off on updating the contributing instructions for this reason.

EDIT: Joined the dev meeting - @keewis doesn't think its a bad idea to fully migrate dev instructions from conda to Pixi. Later (if people really want conda instructions) we can show how to use pixi to export a conda compatible env file - no need for us to maintain two separate env files.


I think that's about it! I don't think I've forgotten anything, but it is late on a Friday so maybe - will update if that's the case :)

Let me know if you want me to drop by the dev meeting on 5 Nov - but I'm happy to keep this async otherwise.


(🎉 for my first significant contribution to Xarray!!!)

- Using the bare-minimum.yml requirements file to act as a starting point to build the composable environments
- Add pixi.lock to gitignore (no need to commit lock files in library repos)
- Update .gitattributes (automatically done by pixi)
- Configure xarray as source dependency with dynamic versioning
Already migrated to pixi
Update requirements files to remove deps handled by Pixi
@lucascolley
Copy link

I think this would be somewhat feasible once we can build all the projects we are interested in with pixi-build. I guess we are wandering a bit off-topic from this PR, though.

VeckoTheGecko added a commit to VeckoTheGecko/xarray that referenced this pull request Nov 19, 2025
Add GitHub Codespaces config following https://pixi.sh/latest/integration/editor/vscode/#devcontainer-extension allowing people to develop from anywhere.

Waiting for pydata#10888
@VeckoTheGecko
Copy link
Contributor Author

VeckoTheGecko commented Dec 2, 2025

The current environment names are based on the original environment.yml files that they replace. This was done for traceability, and for familiarity for current devs - but I actually think they are more confusing than they need to be in this new setup. Its not clear which environment is the "go-to" test environment, and the namings are more verbose than they need to be . I propose the following renames:

diff --git a/pixi.toml b/pixi.toml
index ad51eee6..1086edfd 100644
--- a/pixi.toml
+++ b/pixi.toml
@@ -13,7 +13,7 @@ depends-on = [
 [environments]
 # Testing
 # test-just-xarray = { features = ["test"] } # https://github.com/pydata/xarray/pull/10888/files#r2511336147
-test-all-but-numba = { features = [
+test-no-numba = { features = [
   "py313",
   "test",
   "backends",
@@ -22,7 +22,7 @@ test-all-but-numba = { features = [
   "viz",
   "extras",
 ] }
-test-all-but-dask = { features = [
+test-no-dask = { features = [
   "py312",
   "test",
   "backends",
@@ -31,7 +31,7 @@ test-all-but-dask = { features = [
   "viz",
   "extras",
 ] }
-test-all-deps-py313 = { features = [
+test = { features = [
   "py313",
   "test",
   "backends",
@@ -49,7 +49,7 @@ test-nightly = { features = [
 ], no-default-feature = true }
 
 
-test-all-deps-py311 = { features = [
+test-py311 = { features = [
   "py311",
   "test",
   "backends",
@@ -60,7 +60,7 @@ test-all-deps-py311 = { features = [
   "extras",
 ] }
 
-test-with-typing-py311 = { features = [
+test-py311-with-typing = { features = [
   "py311",
   "test",
   "backends",
@@ -72,7 +72,7 @@ test-with-typing-py311 = { features = [
   "typing",
 ] }
 
-test-with-typing-py313 = { features = [
+test-with-typing = { features = [
   "py313",
   "test",
   "backends",

@dcherian
Copy link
Contributor

dcherian commented Dec 2, 2025

@VeckoTheGecko I agree with your renaming. Please push that change and I'll merge. This is a massive improvement, and has taken a lot of effort. I'd like to merge ASAP

@VeckoTheGecko
Copy link
Contributor Author

@dcherian done

@dcherian
Copy link
Contributor

dcherian commented Dec 2, 2025

upstream tests are failing on main too: #10957

Thanks @VeckoTheGecko . Great work! 👏🏾

@dcherian dcherian merged commit 650dd62 into pydata:main Dec 2, 2025
37 of 41 checks passed
@dcherian
Copy link
Contributor

dcherian commented Dec 2, 2025

Looks like we may have lost the flaky test run?

@shoyer
Copy link
Member

shoyer commented Dec 2, 2025

Looks like we may have lost the flaky test run?

I'm OK losing the flaky test run! In my experience these provide more frustration than value.

@dcherian
Copy link
Contributor

dcherian commented Dec 2, 2025

Also we seem to have two ubuntu-latest | test runs in https://github.com/pydata/xarray/actions/runs/19867294426/job/56933507021?pr=10969 .

@kmuehlbauer
Copy link
Contributor

Looks like one of them is the flaky-test:

env:
  FORCE_COLOR: 3
  PIXI_VERSION: v0.58.0
  TODAY: 2025-12-02
  PYTHON_VERSION: 
  PYTEST_ADDOPTS: -m 'flaky or network' --run-flaky --run-network-tests -W default

VeckoTheGecko added a commit to VeckoTheGecko/xarray that referenced this pull request Dec 2, 2025
Add GitHub Codespaces config following https://pixi.sh/latest/integration/editor/vscode/#devcontainer-extension allowing people to develop from anywhere.

Waiting for pydata#10888
@VeckoTheGecko
Copy link
Contributor Author

Just posted #10970

@JJFlorian
Copy link

JJFlorian commented Dec 3, 2025

Nice! I love this one. Great job @VeckoTheGecko

@VeckoTheGecko VeckoTheGecko deleted the pixi-dust branch December 3, 2025 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Automation Github bots, testing workflows, release automation CI Continuous Integration tools dependencies Pull requests that update a dependency file run-benchmark Run the ASV benchmark workflow run-pyright Run pyright type checker run-slow-hypothesis Run slow hypothesis tests run-upstream Run upstream CI topic-arrays related to flexible array support topic-documentation topic-plotting topic-rolling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using Pixi for environment management

9 participants